#include "rs_test.h"

#include <QDebug>

#include "microscheme.h"
#include "instantiator.h"
#include "realelement.h"
#include "inelement.h"
#include "wire.h"
#include "node.h"

RS_Test::RS_Test() : TestCase("RS Test",0,20)
{
}

QVector<SignalContainer*> RS_Test::testIt()
{
    Instantiator& factory = Instantiator::getInstance();

    MicroScheme* scheme = new MicroScheme();
    scheme->ticPerTact = 1;
    scheme->tactCount = timeLength / scheme->ticPerTact;

    InElement* R_in = (InElement*)factory.buildElement("input");
    R_in->name = "R_in";
    scheme->appendObject(R_in);

    InElement* S_in = (InElement*)factory.buildElement("input");
    S_in->name = "S_in";
    scheme->appendObject(S_in);

    RealElement* nand_R = (RealElement*)factory.buildElement("nand2");
    nand_R->setDelay(0);
    scheme->appendObject(nand_R);

    RealElement* nand_S = (RealElement*)factory.buildElement("nand2");
    nand_S->setDelay(0);
    scheme->appendObject(nand_S);

    //Обязательно назначить сигналы по-умолчанию, если учитываются задержки
    nand_R->pins[1]->defaultSignal = 1;
    nand_R->setDefaultSignal(0);

    nand_S->pins[1]->defaultSignal = 1;
    nand_S->setDefaultSignal(0);

    //# Провода
    Wire* w_RI_R0 = new Wire();
    scheme->appendObject(w_RI_R0);

    Wire* w_SI_S0 = new Wire();
    scheme->appendObject(w_SI_S0);

    Wire* w_R2_S1 = new Wire();
    scheme->appendObject(w_R2_S1);

    Wire* w_S2_R1 = new Wire();
    scheme->appendObject(w_S2_R1);

    //# Соединения

    w_RI_R0->connectPins(R_in->pins.at(0),nand_R->pins.at(0));
    w_SI_S0->connectPins(S_in->pins.at(0),nand_S->pins.at(0));

    w_R2_S1->connectPins(nand_R->pins.at(2),nand_S->pins.at(1));
    w_S2_R1->connectPins(nand_S->pins.at(2),nand_R->pins.at(1));

    //# Нудно добавляем сигналы для тестов в источники

    SignalContainer& r_signal = R_in->getSignalCollection();
    SignalContainer& s_signal = S_in->getSignalCollection();

    r_signal.addSignals("1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1");
    s_signal.addSignals("0 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0");

    SignalContainer* sx[4];

    sx[0] = new SignalContainer(R_in->pins.at(0));
    sx[1] = new SignalContainer(S_in->pins.at(0));
    sx[2] = new SignalContainer(nand_R->pins.at(2));
    sx[3] = new SignalContainer(nand_S->pins.at(2));

    scheme->watches.append(sx[0]);
    scheme->watches.append(sx[1]);
    scheme->watches.append(sx[2]);
    scheme->watches.append(sx[3]);

    //Запуск
    scheme->run();

    SignalContainer* s[4];

    s[0] = new SignalContainer(R_in->pins.at(0));
    s[0]->label = "Rx_inp";

    s[1] = new SignalContainer(S_in->pins.at(0));
    s[1]->label = "Sx_inp";

    s[2] = new SignalContainer(nand_R->pins.at(2));
    s[2]->label = "NAND_R";

    s[3] = new SignalContainer(nand_S->pins.at(2));
    s[3]->label = "NAND_S";

    QVector<SignalContainer*> results;

    //Косяк, нужно скопировать данные
    for (int j = 0; j < 4; j++)
    {
        //qDebug() << "Index: " << j << GetSignalsX(sx[j]) << endl;
        for (int i = 0; i < sx[j]->getItems().count(); i++)
        {
            s[j]->addInterval(sx[j]->getItems().at(i));
        }
        results.append(s[j]);
    }

    //Схема удалит после себя все элементы
    delete scheme;

    return results;
}
